Skip to content

🍞 feat: Start Standalone Bun and Hono RAG Service - #330

Open
lia-by-librechat[bot] wants to merge 6 commits into
mainfrom
lia/document-extraction-contract
Open

lia-by-librechat[bot] wants to merge 6 commits into
mainfrom
lia/document-extraction-contract

Conversation

@lia-by-librechat

@lia-by-librechat lia-by-librechat Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Start the new standalone Bun/Hono RAG service, under service/, with an opt-in DOCX POST /v1/extract profile. This replaces the earlier Python implementation on this PR branch. It is not a Hono proxy: extraction runs through the Node AnyDoc native binding in killable Bun child processes.

The base-to-head diff contains no changes to Python application code, its requirements, its existing CI job, database schema, ingestion or /text. The old service remains the compatibility and rollback path. No LibreChat caller is cut over yet, and the new service does not yet implement retrieval, embeddings, reranking or PDF/OCR support. Do not repoint LibreChat's existing RAG_API_URL until its migration and remaining endpoint contracts are implemented.

Mechanism

Bun listener + Hono (port 8001)
  -> strict RAG JWT, document scope
  -> bounded FIFO admission BEFORE body consumption
  -> streamed multipart staging with body/file/part limits
  -> isolated Bun child: validate ZIP -> AnyDoc 0.1.3 -> typed result
  -> bounded IPC -> reaping -> temporary cleanup -> release slot
  • Starts without Python, pgvector, embedding credentials or a provider health check. The standalone image contains no Python runtime. The default Python Docker images are not replaced.
  • Disabled by default, with no registered extraction route when off.
  • Dedicated RAG_JWT_SECRET, expiry/subject/issuer/audience validation and rag:documents; inference-only and legacy session tokens are refused. Startup refuses using the application session key as the service key.
  • Existing document-v1 response shape and exact Markdown output are preserved on Marco's DOCX fixture. Parser provenance is pinned to AnyDoc 0.1.3. Package relationships and content types detect embedded artwork/objects even without an image filename extension, and mark the result partial; thumbnail artwork does not. The root OPC relationship resolves the main document, including nonconventional package locations. No hosted OCR or fallback occurs inside the endpoint.
  • Limits cover actual streamed HTTP bytes, file bytes, serialized output on both sides, actual inflated ZIP bytes, entry counts, concurrent work and queue length. All extraction operations share an overall deadline. Private random temp directories contain no user-controlled filesystem path.
  • Timeout/abort/disconnect kills and reaps the child before cleanup and slot reuse. The listener idle timeout exceeds the bounded application deadline. Early body refusal cancels the upstream producer before releasing its reader lock. Queued cancellation removes waiting work. The child receives no service key or provider credentials and cannot automatically reload dotenv files.
  • Separate Bun Dockerfile and CI lane with native contract tests, typecheck, formatting, image build and real HTTP/native smoke in the Python-free image.

Verification

Check Result
Bun native/service regression tests 28 passed on pushed head
TypeScript (tsc --noEmit) Passed on pushed head
Prettier and git diff --check Passed before final push; dispatched on pushed head
Independent Bun image build Passed
Real container listener + health + native DOCX Passed on pushed head in the Python-free image
Python application/requirements/CI compatibility Exact base-to-head diff is empty for these paths

Tests preserve the Python prototype's golden DOCX contract and cover partial media, auth and scope denial, disabled-route behavior, MIME/profile routing, malformed/duplicate multipart, chunked input ceilings, archive size and entry refusals, empty extraction, IPC overproduction, crash/malformed child output, timeout, cancellation/retry, admission-before-body reads, FIFO queued cancellation, and real Bun HTTP disconnects. Only crash/hang/overproduction programs are injected; successful extraction uses the real pinned native binding.

The first independent review returned three P2 findings (non-image artwork filenames, listener idle timeout, relocated main document), all fixed in c967dee985ea26d1de7dd77fcd1b37cbd05f8c4d with regressions. Two additional self-check P2 findings (body producer cancellation and child dotenv loading) are fixed in the same head. No findings were rejected. A fresh independent review of that exact pushed head is running alongside CI. Neither old CI results nor Python prototype tests are presented as covering the new Bun implementation.

Deliberate boundaries

This is the first service slice, not a complete Python replacement. No performance benchmark, browser/LibreChat integration, reranking-quality evaluation, PDF fidelity run or traffic cutover is part of this head. Strict scoped RAG token minting must be wired in the forthcoming LibreChat adapter. completeness is conservative known-omission reporting, not a universal proof of inspectability. Concurrency limits are per process, not billing quotas.

EXTRACTION.md records the independent install/image commands, config, wire contract, error taxonomy, compatibility limits and next slice. Keep raw text, semantic extraction, rich HTML preview and complete content inspection distinct as consumers migrate.

Graph checks used rag_api/lia/document-extraction-contract at 15d84b85443f8cf4e23d083c4af6b135ce3f5344 for removing the old Python additions, supplemented by source/string inspection. The new service/ sources were local-only during those checks. Full graph dependency closure was not computed.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Ready for review at pushed head a59e002cc71fc761873d6ce0957038967efb065a.

This is a disabled-by-default DOCX document-v1 extraction endpoint using the pinned AnyDoc Python binding. It leaves /text, RAG ingestion, authentication for existing routes, and LibreChat callers unchanged. The new native-worker test fixture comes from Marco's AnyDoc PR #14701.

Verification on this head: 323 non-container tests passed, 6 skipped; Black, compilation, pip compatibility, and diff checks passed. Container-backed PostgreSQL verification was attempted but blocked by an inaccessible localhost port from the sandbox; the CI lane will exercise it.

Subsystem review covered parser refusal before fallback, bounded input/output and admission, media-omission signaling, auth gates, worker crash/timeout/cancellation and temp cleanup, legacy /text, and mixed-version deployment. Remaining known gaps are called out in the PR description: multipart bodies spool before the route limit, the main app still needs embedding/vector startup, strict-scoped JWT migration is separate, and no LibreChat caller has cut over.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Ready for review at new pushed head 15d84b85443f8cf4e23d083c4af6b135ce3f5344.

Follow-up to the first working pass: the opt-in extraction router is now absent at startup unless RAG_EXTRACTION_API_ENABLED=true. Returning 404 inside a registered multipart route still allowed the framework to parse/spool the upload; the new head closes that default-off exposure. A cold-start test checks both flag states and confirms that the native AnyDoc module stays unloaded in the API process. The existing /text test still exercises the production application.

The real HTTP DOCX/worker contract checks pass (21 tests). The complete non-container suite has been dispatched on this head. The prior head passed GitHub CI including its configured database lane, but that CI result does not cover this follow-up commit; the new CI run is the authoritative one. The sandbox cannot reach its own Docker-published localhost port, so local SQL assertions remain unverified.

@lia-by-librechat lia-by-librechat Bot changed the title 📄 feat: Add Opt-In DOCX Extraction Profile 🍞 feat: Start Standalone Bun and Hono RAG Service Sep 30, 2026
@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Ready for review at exact pushed head 9324808c0db895fb138c1e67d1f79edbfd64c318.

This head starts the standalone Bun/Hono service, not the prior Python extension. It removes the branch's Python application, dependency and CI additions, preserving those paths exactly as on main. It does not proxy to Python: DOCX parsing uses the pinned Node AnyDoc binding in isolated, killable Bun child processes. The new service has independent startup, image, CI, strict service auth, pre-body admission, streaming limits and typed errors/results. No LibreChat traffic is switched and no retrieval/reranking parity is claimed yet.

The exact Markdown fixture is preserved. Real native tests cover auth denial, partial media, unsafe input/output, crash/deadline/cancellation/retry, bounded FIFO and actual Bun HTTP disconnect cleanup. A separately built Python-free container passed its real HTTP/health/native DOCX smoke. Exact-head local checks and both CI lanes are running, together with an independent read-only review. Results of the old Python implementation are not reused as evidence for this head.

@lia-by-librechat

Copy link
Copy Markdown
Contributor Author

Ready for review at exact pushed head c967dee985ea26d1de7dd77fcd1b37cbd05f8c4d.

The independent first-round review returned three P2 findings, all supported and fixed in this commit:

ID Finding Disposition
R1 Embedded artwork with non-image filenames could claim complete text Fixed; package content types and relationships participate in omission detection; native .bin artwork regressions
R2 Bun's default idle timeout could reset a parse before its deadline Fixed; listener timeout exceeds the validated deadline; real >10-second listener regression
R3 Valid DOCX main document outside word/document.xml was refused Fixed; resolve the root OPC relationship; relocated golden native fixture regression

Two self-check findings are also fixed: cancel unread body producers before releasing their reader lock (assertion fails against previous head), and disable Bun dotenv loading in native children (canary regression). Metadata XML refuses DTDs and external main-part targets. These changes preserve the old Python app and its requirements/CI unchanged.

The expanded local suite passed 28 tests before this push. Exact-head tests, typecheck, formatting, runtime dependency audit and Python-free container/native smoke are now dispatched alongside both CI lanes. A fresh independent review targets this SHA; the first-round review does not cover the new head.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant